using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using Beetle;

[DefaultMember("Item")]
internal class aq : IChannel
{
	internal const string a = "<Exponent>{0}</Exponent>";

	[ac]
	public static string b = "PFJTQUtleVZhbHVlPjxNb2R1bHVzPnBrZVREcm1COGNRVUM3emQvQ1N0ZHIwMnZtZ24xVHNjS0dWREx1RFRlSjFJM3prelFtbFlBeS9GdlJPVVRJZnZKbmYvc05yRXNsODZvNTBYYVRVWFF5NmtQbTVLbWFvaTNBMjRFYWpFTEtocTcrbE9qakY3akM3V0E1RHdJT2pUYjR3Wi8zcnphb3VWYmR5VVlFTTZYUlRGVVZ4ZUlLZ3BsenBWVllQanY0dUQzUDV5OVhWS3RUM2x0Y3BOUFZrK0FKakt3YXNaUlE0YS9yM0l0OUZsNGlzS2kxMjJWV1dwWmQzdENhK1E4dXNYMVZ2RFpZdVJFZXFsNWllazIxY2E4YWFMVDF6eFpxL2ovNlYrdnlVeFFIM0dJZmFBSThOaXBHMDludTlFVTZDSHFqbFF1Q1dCZkg4NjVDYnJqTWlSbU01S0J5QXNDNUphekROU01yUm81UT09PC9Nb2R1bHVzPjxFeHBvbmVudD5BUUFCPC9FeHBvbmVudD48L1JTQUtleVZhbHVlPg==";

	private static long m_c = 0L;

	internal bool d;

	public bool e;

	internal int f = -1;

	internal int g;

	internal TcpServer h;

	private Hashtable i = new Hashtable(4);

	public string j = "";

	public long k;

	public long l;

	public bool m;

	public int n = Environment.TickCount;

	public EventSendMessageCompleted o;

	internal bool p = true;

	internal bool q = true;

	internal bool r = true;

	internal Package s;

	public EventDataReceive t;

	public EventMessageWriter u;

	public EventMessageWriter v;

	private EventChannelError w;

	private EventChannelDisposed x;

	private bool y;

	internal static string z = "V/r2I2CpRaI=";

	public bool aa;

	internal k ab;

	internal at ac;

	internal at ad;

	internal at ae;

	internal ChannelReceiveEventArgs af = new ChannelReceiveEventArgs();

	private Socket ag;

	private bool ah;

	private aa ai = new aa();

	private ai aj = new ai();

	private IDataWriter ak;

	private int al;

	internal Queue<IMessage> am = new Queue<IMessage>(256);

	internal SendMessageCompletedArgs an = new SendMessageCompletedArgs();

	internal bool ao;

	internal bool ap;

	internal bool aq;

	[CompilerGenerated]
	private ChannelStatus ar;

	[CompilerGenerated]
	private DateTime @as;

	[CompilerGenerated]
	private object at;

	[CompilerGenerated]
	private Encoding au;

	[CompilerGenerated]
	private long av;

	[CompilerGenerated]
	private IPEndPoint aw;

	[CompilerGenerated]
	private string ax;

	[CompilerGenerated]
	private LinkedListNode<LRUDetect.Node> ay;

	private static void a(aq A_0)
	{
		lock (typeof(aq))
		{
			A_0.set_Item("_data", 255);
			global::aq.m_c++;
			A_0.a(global::aq.m_c);
		}
	}

	[SpecialName]
	public Hashtable g()
	{
		return i;
	}

	[SpecialName]
	public object get_Item(string name)
	{
		return i[name];
	}

	[SpecialName]
	public void set_Item(string name, object value)
	{
		i[name] = value;
	}

	[SpecialName]
	public bool get_EnabledSendCompeletedEvent()
	{
		return m;
	}

	[SpecialName]
	public void set_EnabledSendCompeletedEvent(bool value)
	{
		m = value;
	}

	[SpecialName]
	[CompilerGenerated]
	public ChannelStatus get_Status()
	{
		return ar;
	}

	[SpecialName]
	[CompilerGenerated]
	public void set_Status(ChannelStatus value)
	{
		ar = value;
	}

	[SpecialName]
	[CompilerGenerated]
	public DateTime get_CreateTime()
	{
		return @as;
	}

	[SpecialName]
	[CompilerGenerated]
	public void a(DateTime A_0)
	{
		@as = A_0;
	}

	[SpecialName]
	public int get_TickCount()
	{
		return n;
	}

	[SpecialName]
	[CompilerGenerated]
	public object get_Tag()
	{
		return at;
	}

	[SpecialName]
	[CompilerGenerated]
	public void set_Tag(object value)
	{
		at = value;
	}

	public Package SetPackage<T>() where T : Package
	{
		s = (Package)Activator.CreateInstance(typeof(T), this);
		s.LittleEndian = get_LittleEndian();
		return s;
	}

	[SpecialName]
	public Package get_Package()
	{
		return s;
	}

	[SpecialName]
	public EventSendMessageCompleted get_SendMessageCompleted()
	{
		return o;
	}

	[SpecialName]
	public void set_SendMessageCompleted(EventSendMessageCompleted value)
	{
		o = value;
	}

	[SpecialName]
	public EventDataReceive get_DataReceive()
	{
		return t;
	}

	[SpecialName]
	public void set_DataReceive(EventDataReceive value)
	{
		t = value;
	}

	[SpecialName]
	public EventMessageWriter get_MessageWriting()
	{
		return u;
	}

	[SpecialName]
	public void set_MessageWriting(EventMessageWriter value)
	{
		u = value;
	}

	[SpecialName]
	public EventMessageWriter get_MessageWrited()
	{
		return v;
	}

	[SpecialName]
	public void set_MessageWrited(EventMessageWriter value)
	{
		v = value;
	}

	[SpecialName]
	public void add_ChannelError(EventChannelError value)
	{
		EventChannelError eventChannelError = w;
		EventChannelError eventChannelError2;
		do
		{
			eventChannelError2 = eventChannelError;
			EventChannelError value2 = (EventChannelError)Delegate.Combine(eventChannelError2, value);
			eventChannelError = Interlocked.CompareExchange(ref w, value2, eventChannelError2);
		}
		while ((object)eventChannelError != eventChannelError2);
	}

	[SpecialName]
	public void remove_ChannelError(EventChannelError value)
	{
		EventChannelError eventChannelError = w;
		EventChannelError eventChannelError2;
		do
		{
			eventChannelError2 = eventChannelError;
			EventChannelError value2 = (EventChannelError)Delegate.Remove(eventChannelError2, value);
			eventChannelError = Interlocked.CompareExchange(ref w, value2, eventChannelError2);
		}
		while ((object)eventChannelError != eventChannelError2);
	}

	[SpecialName]
	public void add_ChannelDisposed(EventChannelDisposed value)
	{
		EventChannelDisposed eventChannelDisposed = x;
		EventChannelDisposed eventChannelDisposed2;
		do
		{
			eventChannelDisposed2 = eventChannelDisposed;
			EventChannelDisposed value2 = (EventChannelDisposed)Delegate.Combine(eventChannelDisposed2, value);
			eventChannelDisposed = Interlocked.CompareExchange(ref x, value2, eventChannelDisposed2);
		}
		while ((object)eventChannelDisposed != eventChannelDisposed2);
	}

	[SpecialName]
	public void remove_ChannelDisposed(EventChannelDisposed value)
	{
		EventChannelDisposed eventChannelDisposed = x;
		EventChannelDisposed eventChannelDisposed2;
		do
		{
			eventChannelDisposed2 = eventChannelDisposed;
			EventChannelDisposed value2 = (EventChannelDisposed)Delegate.Remove(eventChannelDisposed2, value);
			eventChannelDisposed = Interlocked.CompareExchange(ref x, value2, eventChannelDisposed2);
		}
		while ((object)eventChannelDisposed != eventChannelDisposed2);
	}

	public aq(Socket A_0)
	{
		if (!TcpUtils.a)
		{
			throw NetTcpException.NotInitialize();
		}
		set_Coding(Encoding.UTF8);
		ag = A_0;
		a(DateTime.Now);
		ac = TcpUtils.c();
		ad = TcpUtils.e();
		ae = TcpUtils.d();
		a(this);
		a((IPEndPoint)A_0.RemoteEndPoint);
		ak = new x(TcpUtils.f);
		((x)ak).set_Channel(this);
		af.Channel = this;
		ab = global::k.f();
		y = true;
	}

	[SpecialName]
	public bool get_LittleEndian()
	{
		return y;
	}

	[SpecialName]
	public void set_LittleEndian(bool value)
	{
		y = value;
		if (get_Package() != null)
		{
			get_Package().LittleEndian = value;
		}
		ak.LittleEndian = value;
	}

	[SpecialName]
	public Socket get_Socket()
	{
		return ag;
	}

	internal void a(bool A_0)
	{
		ah = A_0;
	}

	public bool Send(object message)
	{
		if (s != null && message != null)
		{
			return b((IMessage)s.WriteCast(message));
		}
		return b((IMessage)message);
	}

	private bool b(IMessage A_0)
	{
		if (ag == null || aq || ao)
		{
			if (A_0 is ICounterMessage)
			{
				((ICounterMessage)A_0).Decrement();
			}
			return false;
		}
		if (q)
		{
			lock (am)
			{
				if (A_0 != null)
				{
					am.Enqueue(A_0);
				}
				if (am.Count > 0 && !ah && !aq)
				{
					a(A_0: true);
					((am)ai).f = this;
					ad.a(ai);
				}
			}
		}
		else if (A_0 != null)
		{
			try
			{
				lock (this)
				{
					while (ah && !aq)
					{
						Thread.Sleep(1);
					}
					a(A_0: true);
					a(A_0);
				}
			}
			catch (Exception exception)
			{
				InvokeChannelError(new ChannelErrorEventArgs
				{
					Channel = this,
					Exception = exception
				});
			}
		}
		return true;
	}

	[SpecialName]
	public int f()
	{
		return am.Count;
	}

	private void a(IMessage A_0)
	{
		if (m && an.Messages.Count > 0)
		{
			an.Messages.Clear();
		}
		ak.Reset();
		if (m)
		{
			an.Messages.Add(A_0);
		}
		if (u == null)
		{
			A_0.Save(ak);
		}
		else
		{
			u(A_0, ak);
			if (v != null)
			{
				v(A_0, ak);
			}
		}
		Interlocked.Increment(ref TcpUtils.SendMessages);
		if (A_0 is ICounterMessage)
		{
			((ICounterMessage)A_0).Decrement();
		}
		b(((x)ak).i());
	}

	internal void h()
	{
		lock (am)
		{
			if (am.Count == 0)
			{
				return;
			}
			if (m && an.Messages.Count > 0)
			{
				an.Messages.Clear();
			}
			if (get_Socket() == null || aq)
			{
				while (am.Count > 0)
				{
					IMessage message = am.Dequeue();
					if (message is ICounterMessage)
					{
						((ICounterMessage)message).Decrement();
					}
					if (m)
					{
						an.Messages.Add(message);
					}
				}
				an.Success = false;
				b();
				return;
			}
			ak.Reset();
			while (am.Count > 0)
			{
				IMessage message = am.Dequeue();
				if (m)
				{
					an.Messages.Add(message);
				}
				if (u == null)
				{
					message.Save(ak);
				}
				else
				{
					u(message, ak);
					if (v != null)
					{
						v(message, ak);
					}
				}
				Interlocked.Increment(ref TcpUtils.SendMessages);
				if (message is ICounterMessage)
				{
					((ICounterMessage)message).Decrement();
				}
			}
		}
		b(((x)ak).i());
	}

	private void a(ax A_0)
	{
		y y2 = null;
		int num = 0;
		try
		{
			while (A_0.b != null)
			{
				y2 = A_0.b;
				num = 0;
				while (num < y2.i && !aq)
				{
					int num2 = get_Socket().Send(y2.g, num, y2.i - num, SocketFlags.None);
					num += num2;
					if (TcpUtils.Statistics)
					{
						lock (TcpUtils.d)
						{
							TcpUtils.SendBytes += num2;
							l += num2;
							TcpUtils.SendDataIO++;
						}
					}
				}
				A_0.e();
			}
		}
		finally
		{
			A_0.d();
		}
		a(A_0: false);
		Send(null);
	}

	internal void b(ax A_0)
	{
		y y2 = null;
		try
		{
			if (e)
			{
				a(A_0);
				return;
			}
			y2 = A_0.b;
			if (y2 == null)
			{
				return;
			}
			if (!aq)
			{
				TcpUtils.a();
				av av2 = y2.a();
				av2.c = this;
				av2.UserToken = A_0;
				if (!get_Socket().SendAsync(av2))
				{
					av2.a(av2);
				}
			}
			else
			{
				A_0.d();
			}
		}
		catch (Exception ex)
		{
			A_0.d();
			throw ex;
		}
	}

	public void BeginReceive()
	{
		if (p)
		{
			aj.f = this;
			ae.a(aj);
		}
		else
		{
			d();
		}
	}

	internal void d()
	{
		if (aq || !ab.a)
		{
			return;
		}
		TcpUtils.a();
		av av2 = TcpUtils.e.d();
		av2.c = this;
		try
		{
			if (!get_Socket().ReceiveAsync(av2))
			{
				av2.d(av2);
			}
		}
		catch (Exception exception)
		{
			av2.f();
			InvokeChannelError(new ChannelErrorEventArgs
			{
				Channel = this,
				Exception = exception
			});
		}
	}

	internal void b()
	{
		try
		{
			if (o != null)
			{
				an.Channel = this;
				o(this, an);
			}
		}
		catch
		{
		}
		finally
		{
			an.Channel = null;
		}
	}

	internal void a(ChannelReceiveEventArgs A_0)
	{
		b(A_0);
	}

	protected virtual void b(ChannelReceiveEventArgs A_0)
	{
		if (t != null && !ap)
		{
			t(this, A_0);
		}
	}

	public void InvokeChannelError(ChannelErrorEventArgs e)
	{
		try
		{
			ThreadPool.QueueUserWorkItem(a, e);
		}
		catch
		{
		}
	}

	protected virtual void a(object A_0)
	{
		ChannelErrorEventArgs channelErrorEventArgs = (ChannelErrorEventArgs)A_0;
		try
		{
			if (w != null && !aq)
			{
				w(this, channelErrorEventArgs);
			}
		}
		catch
		{
		}
		try
		{
			if (channelErrorEventArgs.Exception is SocketException || channelErrorEventArgs.Exception is ObjectDisposedException || channelErrorEventArgs.Exception is NetTcpException)
			{
				j = "Socket Disposed!";
				Dispose();
			}
		}
		catch
		{
		}
	}

	protected virtual void a(ChannelDisposedEventArgs A_0)
	{
		if (x != null)
		{
			x(this, A_0);
		}
	}

	[SpecialName]
	[CompilerGenerated]
	public Encoding get_Coding()
	{
		return au;
	}

	[SpecialName]
	[CompilerGenerated]
	public void set_Coding(Encoding value)
	{
		au = value;
	}

	[SpecialName]
	[CompilerGenerated]
	public long get_ClientID()
	{
		return av;
	}

	[SpecialName]
	[CompilerGenerated]
	internal void a(long A_0)
	{
		av = A_0;
	}

	private void a()
	{
		if (this.h != null)
		{
			ao = this.h.o.Count > global::o.a;
		}
	}

	[SpecialName]
	public TcpServer get_Server()
	{
		return this.h;
	}

	[SpecialName]
	internal void a(TcpServer A_0)
	{
		this.h = A_0;
		a();
	}

	[SpecialName]
	[CompilerGenerated]
	public IPEndPoint get_EndPoint()
	{
		return aw;
	}

	[SpecialName]
	[CompilerGenerated]
	internal void a(IPEndPoint A_0)
	{
		aw = A_0;
	}

	[SpecialName]
	[CompilerGenerated]
	public string get_Name()
	{
		return ax;
	}

	[SpecialName]
	[CompilerGenerated]
	public void set_Name(string value)
	{
		ax = value;
	}

	internal void c()
	{
		ap = true;
		set_Node(null);
		TcpServer.ReleaseSocket(get_Socket());
		ag = null;
		if (ak != null)
		{
			((x)ak).set_Channel(null);
			((x)ak).b(A_0: true);
		}
		if (s != null)
		{
			s.Dispose();
			s = null;
		}
		try
		{
			lock (am)
			{
				while (am.Count > 0)
				{
					IMessage message = am.Dequeue();
					if (message is ICounterMessage)
					{
						((ICounterMessage)message).Decrement();
					}
				}
			}
		}
		catch
		{
		}
		aj.f = null;
		aj = null;
		((am)ai).f = null;
		ai = null;
		u = null;
		i.Clear();
		ak = null;
		af.Channel = null;
		af = null;
		a((TcpServer)null);
		set_Tag(null);
	}

	[SpecialName]
	public bool get_IsDisposed()
	{
		return aq;
	}

	public void Dispose()
	{
		if (aq)
		{
			return;
		}
		lock (this)
		{
			if (!aq)
			{
				aq = true;
				ChannelDisposedEventArgs channelDisposedEventArgs = new ChannelDisposedEventArgs();
				channelDisposedEventArgs.Message = am;
				channelDisposedEventArgs.Clean = true;
				channelDisposedEventArgs.Channel = this;
				try
				{
					a(channelDisposedEventArgs);
				}
				catch
				{
				}
				if (channelDisposedEventArgs.Clean)
				{
					channelDisposedEventArgs.Channel = null;
					c();
				}
				else
				{
					ChannelDisposedQueue.DisposedQueue.Add(channelDisposedEventArgs);
				}
			}
		}
	}

	[SpecialName]
	[CompilerGenerated]
	public LinkedListNode<LRUDetect.Node> get_Node()
	{
		return ay;
	}

	[SpecialName]
	[CompilerGenerated]
	public void set_Node(LinkedListNode<LRUDetect.Node> value)
	{
		ay = value;
	}

	public void TimeOut()
	{
		j = "time out!";
		Dispose();
	}

	public long GetSendBytes()
	{
		return l;
	}

	public long GetReceiveBytes()
	{
		return k;
	}

	public int GetSendQueues()
	{
		return am.Count;
	}

	public int GetReceiveQueues()
	{
		return this.g;
	}

	public string GetCloseStatus()
	{
		return j;
	}

	public bool Send<T, T1, T2>(ICallBackMessage msg, EventCallBackHandler<T> callback, EventCallBackHandler<T1> callback1, EventCallBackHandler<T2> callback2, object usertoken = null) where T : ICallBackMessage where T1 : ICallBackMessage where T2 : ICallBackMessage
	{
		if (aq)
		{
			return false;
		}
		if (msg.MessageID == 0)
		{
			msg.MessageID = Interlocked.Increment(ref al);
		}
		ag ag2 = new ag();
		ag2.b(typeof(T), callback);
		ag2.b(typeof(T1), callback1);
		ag2.b(typeof(T2), callback2);
		ag2.b(usertoken);
		if (get_Package() != null)
		{
			get_Package().a(msg.MessageID, ag2);
		}
		return Send(msg);
	}

	public bool Send<T, T1>(ICallBackMessage msg, EventCallBackHandler<T> callback, EventCallBackHandler<T1> callback1, object usertoken = null) where T : ICallBackMessage where T1 : ICallBackMessage
	{
		if (aq)
		{
			return false;
		}
		if (msg.MessageID == 0)
		{
			msg.MessageID = Interlocked.Increment(ref al);
		}
		ag ag2 = new ag();
		ag2.b(typeof(T), callback);
		ag2.b(typeof(T1), callback1);
		ag2.b(usertoken);
		if (get_Package() != null)
		{
			get_Package().a(msg.MessageID, ag2);
		}
		return Send(msg);
	}

	public bool Send<T>(ICallBackMessage msg, EventCallBackHandler<T> callback, object usertoken = null) where T : ICallBackMessage
	{
		if (aq)
		{
			return false;
		}
		if (msg.MessageID == 0)
		{
			msg.MessageID = Interlocked.Increment(ref al);
		}
		ag ag2 = new ag();
		ag2.b(typeof(T), callback);
		ag2.b(usertoken);
		if (get_Package() != null)
		{
			get_Package().a(msg.MessageID, ag2);
		}
		return Send(msg);
	}
}
